// 类的声明头文件
#include "datainfowindow.h"
// 设计的UI界面头文件（一个类对应一个UI界面）
#include "ui_datainfowindow.h"

// 自定义的摄像头头文件
#include "Camera.h"

// 自定义的数据记录查询头文件
#include "dataquerywindow.h"

// 自定义的deepseek大模型头文件
#include "deepseekwindow.h"

// debug调试打印数据头文件
#include <QDebug>

// 消息框头文件
#include <QMessageBox>

// QSsh远程传输服务器命令库（QSsh是第三方库）
//#include <QSsh>

// 文件操作头文件
#include <QFile>

// 网络进程操作头文件
#include <QProcess>

// 定时器操作头文件
#include <QTimer>

// pscp命令头文件
#include <QProcess>
#include <QMessageBox>
#include <QString>
#include <QStringList>

DataInfoWindow::DataInfoWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::DataInfoWindow)
{
    // 设置并显示当前界面
    ui->setupUi(this);
    // 调用设置显示数据列表的函数
    setDataList();
}

DataInfoWindow::~DataInfoWindow()
{
    delete ui;
}

// 返回主界面
void DataInfoWindow::on_backButton_clicked()
{
    //因为在跳转时，记录了上一个界面
    //所以可以利用此函数获取当前窗口的父窗口对象指针
    QWidget *parent = this->parentWidget();
    qDebug()<<"parent addr:"<<parent;
    parent->show();//把之前父界面的隐藏状态改为显示状态，显示父界面
    this->close();//关闭当前界面
//    //销毁子界面
//    delete this;  //如果设置了自动销毁，则不需要手动delete
}


//// 创建表
//QSqlQuery query;
//if (!query.exec("CREATE TABLE IF NOT EXISTS photos ("
//               "id INTEGER PRIMARY KEY AUTOINCREMENT, "
//               "name TEXT NOT NULL, "
//                "image_data BLOB, "
//               "create_time TEXT)")) {
//    qDebug() << "Error: Failed to create table." << query.lastError();
//}
// 创建widgetlist表并添加数据
// 插入数据
void DataInfoWindow::setDataList() {
    //初始化表格控件
    //表头
    QStringList headerText;
//    headerText<<QString::fromLocal8Bit("序号")
//                <<QString::fromLocal8Bit("图片名称")
//                <<QString::fromLocal8Bit("图片数据")
//                <<QString::fromLocal8Bit("图片保存时间");
    headerText << "序号" << "图片名称" << "图片保存时间" << "动/植物类型" << "名称" << "百科详情";
    //设置列数
    ui->tableWidget->setColumnCount(6);
    //设置间隔交替颜色
    ui->tableWidget->setAlternatingRowColors(true);
    ui->tableWidget->setColumnHidden(0, true);  // 隐藏 ID 列

    //为表格控件添加 表头
    for (int i=0; i<ui->tableWidget->columnCount(); i++) {
        QTableWidgetItem *item = new QTableWidgetItem; //给每个表格中的单元格 创建一个QTableWidgetItem
        item->setText(headerText.at(i));

        //设置单元格的字体
        QFont itemFont = item->font();
        itemFont.setBold(true);
        itemFont.setPixelSize(24);
        item->setFont(itemFont);

        //将这个单元格设置到 表格控件上
        ui->tableWidget->setHorizontalHeaderItem(i,item);
    }

    //显示所有的数据到控件上
    //1. 连接数据库
    QSqlDatabase db = QSqlDatabase::database(); // 如果已连接，直接获取
    if (!db.isOpen()) {
        db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("my_database.db");
        if (!db.open()) {
            qDebug() << "Error: Database connection failed!" << db.lastError();
            return;
        }
    }
    //2、实例化数据库操作类的对象
    QSqlQuery query;
    //3、准备 sql语句
    QString sql = QString::fromLocal8Bit("select * from photos;");
    //4、执行
    if(!query.exec(sql)){
        QString text = QString("select table error:%1").arg(query.lastError().text());
        QMessageBox::critical(this,"error",text);
    }
    //5、将查询到的结果 更新到UI控件上
    int row=0;

    //数据库内部的指针 刚开始指向的是 第一条记录上面那个位置，所以先用query.next()接口将 指针 偏移到第一个记录的位置
    while (query.next()) { //一条记录
        // 这里的字段顺序需要和列表的表头顺序一致
        int id = query.value("id").toUInt(); // 序号
        QString name = query.value("name").toString(); // 图片名称
//        double image_data = query.value("image_data").toDouble(); // 不会转换
        QString create_time = query.value("create_time").toString(); // 图片保存时间
        QString type_ani_pla = query.value("type_ani_pla").toString(); // 动/植物类型
        QString name_ani_pla = query.value("name_ani_pla").toString(); // 名称
        QString detail_ani_pla = query.value("detail_ani_pla").toString(); // 百科详情

        //将 数据显示到 表格控件上
        //表格控件 需要注意的地方: 在插入数据之前，先新增一行
        qDebug()<<"rowCount:"<<ui->tableWidget->rowCount();
        ui->tableWidget->setRowCount(ui->tableWidget->rowCount() + 1);
        QTableWidgetItem *item ;

        //id
        item = new QTableWidgetItem;
        item->setText(QString::number(id));
        ui->tableWidget->setItem(row,0,item);
        //name
        item = new QTableWidgetItem;
        item->setText(name);
        ui->tableWidget->setItem(row,1,item);
//        //image_data
//        item = new QTableWidgetItem;
//        item->setText(QString::number(image_data));
//        ui->tableWidget->setItem(row,2,item);
        //create_time
        item = new QTableWidgetItem;
        item->setText(create_time);
        ui->tableWidget->setItem(row,2,item);
        //type_ani_pla
        item = new QTableWidgetItem;
        item->setText(type_ani_pla);
        ui->tableWidget->setItem(row,3,item);
        //name_ani_pla
        item = new QTableWidgetItem;
        item->setText(name_ani_pla);
        ui->tableWidget->setItem(row,4,item);
        //detail_ani_pla
        item = new QTableWidgetItem;
        item->setText(detail_ani_pla);
        ui->tableWidget->setItem(row,5,item);
        row++;
    }
}

// 删除记录（列表和数据库记录同时删除）
void DataInfoWindow::on_deleteButton_clicked() {
    qDebug() << "on_deleteButton_clicked:\r\n";

    // 1.获取当前选中行
    int currentRow = ui->tableWidget->currentRow();
    if (currentRow == -1) {
        QMessageBox::warning(this, "警告", "请先选择要删除的行！");
        return;
    }

    // 2.获取隐藏的数据库 ID（假设存储在列 0）
    QString id = ui->tableWidget->item(currentRow, 0)->text();

    // 3.连接数据库
    QSqlDatabase db = QSqlDatabase::database(); // 如果已连接，直接获取
    if (!db.isOpen()) {
        db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("my_database.db");
        if (!db.open()) {
            qDebug() << "Error: Database connection failed!" << db.lastError();
            return;
        }
    }

    // 4.从数据库删除
    QSqlQuery query;
    query.prepare("DELETE FROM photos WHERE id = ?");
    query.addBindValue(id);
    if (!query.exec()) {
        QMessageBox::critical(this, "错误", "数据库删除失败：" + query.lastError().text());
        return;
    }

    // 5.从表格中移除行
    ui->tableWidget->removeRow(currentRow);
    QMessageBox::information(this, "成功", "记录已删除！");
}

// 修改表格数据（列表和数据库记录同时修改）
void DataInfoWindow::on_alterButton_clicked()
{
    qDebug() << "on_alterButton_clicked:\r\n";

    // 获取当前选中单元格
    QTableWidgetItem *currentItem = ui->tableWidget->currentItem();
    if (!currentItem) {
        QMessageBox::warning(this, "警告", "请先选择一个单元格！");
        return;
    }

    int row = currentItem->row();
    int col = currentItem->column();
    QString newValue = currentItem->text();

    // 获取数据库 ID（假设存储在列 0）
    QString id = ui->tableWidget->item(row, 0)->text();

    // 根据列名确定要更新的数据库字段
    QString columnName;
    switch (col) {
        case 1: columnName = "name"; break;
        case 2: columnName = "create_time"; break;
        case 3: columnName = "type_ani_pla"; break;
        case 4: columnName = "name_ani_pla"; break;
        case 5: columnName = "detail_ani_pla"; break;
        default:
            QMessageBox::warning(this, "警告", "不能修改 ID 列！");
            return;
    }

    // 连接数据库
    QSqlDatabase db = QSqlDatabase::database(); // 如果已连接，直接获取
    if (!db.isOpen()) {
        db = QSqlDatabase::addDatabase("QSQLITE");
        db.setDatabaseName("my_database.db");
        if (!db.open()) {
            qDebug() << "Error: Database connection failed!" << db.lastError();
            return;
        }
    }

    // 更新数据库
    QSqlQuery query;
    query.prepare(QString("UPDATE photos SET %1 = ? WHERE id = ?").arg(columnName));
    query.addBindValue(newValue);
    query.addBindValue(id);

    if (query.exec()) {
        QMessageBox::information(this, "成功", "修改已保存！");
    } else {
        QMessageBox::critical(this, "错误", "数据库更新失败：" + query.lastError().text());
        // 恢复原值（可选）
        currentItem->setText(ui->tableWidget->item(row, col)->text());
    }
}

// 点击切换到查询数据信息的界面
void DataInfoWindow::on_queryButton_clicked()
{
    //第一步：创建另一个界面的对象  new MainWindow(this) 把父窗口传递过去，记录从哪一个界面跳转
    DataQueryWindow *dataquerywindow = new DataQueryWindow(this);
    dataquerywindow->setAttribute(Qt::WA_DeleteOnClose);//关闭之后自动销毁对象
    //第二步：显示要跳转的界面
    dataquerywindow->show();
    //第三步：隐藏当前的界面,跳转到另一个界面之后，点击返回按钮还可以返回当前界面
    this->hide();
}

// 点击切换到DeepSeek大模型的界面
void DataInfoWindow::on_deepseekButton_clicked()
{
//    //第一步：创建另一个界面的对象  new MainWindow(this) 把父窗口传递过去，记录从哪一个界面跳转
//    DeepSeekWindow *deepseekwindow = new DeepSeekWindow(this);
//    // 注意：执行该条代码语句，点击x关闭后将会关闭整个应用程序 application ，慎用！
////    deepseekwindow->setAttribute(Qt::WA_DeleteOnClose);//关闭之后自动销毁对象
//    //第二步：显示要跳转的界面
//    deepseekwindow->show();
//    //第三步：隐藏当前的界面,跳转到另一个界面之后，点击返回按钮还可以返回当前界面
//    this->hide();

    DeepSeekWindow *deepseekwindow = new DeepSeekWindow(this);  // this 指定父对象
    deepseekwindow->show();     // 显示子窗口
    this->hide();         // 隐藏父窗口
}

bool DataInfoWindow::checkNetworkConnection(const QString &host) {
    qDebug() << "checkNetworkConnection";
    QProcess ping;
    QStringList args;

#ifdef Q_OS_WIN
    args << "-n" << "1" << "-w" << "2000" << host;  // Windows使用-n和超时参数-w(毫秒)
#else
    args << "-c" << "1" << "-W" << "2" << host;    // Linux/macOS使用-c和-W(秒)
#endif

    ping.start("ping", args);
    if (!ping.waitForFinished(3000)) {  // 总超时3秒
        qDebug() << "Ping failed:" << ping.errorString();
        return false;
    }
    qDebug() << "不超时";
    QString output = QString::fromLocal8Bit(ping.readAllStandardOutput());
    qDebug() << "zhengchang";
    return (ping.exitCode() == 0) && output.contains("TTL=", Qt::CaseInsensitive);
}

// 使用示例
void DataInfoWindow::checkServer() {
    qDebug() << "checkServer";
    qDebug() << !checkNetworkConnection("8.138.215.14");
    if (!checkNetworkConnection("8.138.215.14")) {
        qDebug() << "jinru";
        QMessageBox::warning(this, "警告",
            "实际网络通畅但检测失败\n"
            "可能原因：\n"
            "1. 程序权限不足\n"
            "2. 防病毒软件拦截\n"
            "3. 跨平台参数问题");
        return;
    }
    qDebug() << "继续上传操作";
    // 继续上传操作...
}

// 上传选中记录的图片到服务器
void DataInfoWindow::on_uploadserverButton_clicked()
{
        qDebug() << "on_uploadserverButton_clicked:\r\n";

        // 1. 获取当前选中行
        int currentRow = ui->tableWidget->currentRow();
        if (currentRow == -1) {
            QMessageBox::warning(this, "警告", "请先选择要上传的行！");
            return;
        }

        // 2. 获取图片路径（假设图片路径存储在列2）
        QString imagePath = ui->tableWidget->item(currentRow, 1)->text();
        if (imagePath.isEmpty()) {
            QMessageBox::warning(this, "警告", "该记录没有有效的图片路径！");
            return;
        }

        // 3. 检查文件是否存在
        QFile imageFile(imagePath);
        if (!imageFile.exists()) {
            QMessageBox::critical(this, "错误", "图片文件不存在：" + imagePath);
            return;
        }

        // 检查文件是否存在
        if (!QFile::exists(imagePath)) {
            QMessageBox::critical(this, "错误", "本地图片不存在！");
            return;
        }

        // 检查网络连通性
        QProcess ping;
        ping.start("ping", {"-n", "1", "8.138.215.14"});
        if (!ping.waitForFinished(2000)) {
            QMessageBox::warning(this, "警告", "服务器无法连通！");
            return;
        }
//        else {
//            QMessageBox::information(this, "成功", "服务器连接成功！");
//        }

        // 4. 使用SCP上传文件
        // 修改上传代码段
        QProcess *scp = new QProcess();

        QString pscpPath = "D:\\WorkApp\\PuTTY\\Program Files\\PuTTY\\pscp.exe";
        QStringList arguments;
        arguments << "-pw" << serverPassword; // 不使用 -batch 禁止交互式提示
//        arguments << "-batch" << "-pw" << serverPassword; // 使用 -batch 禁止交互式提示
        arguments << imagePath;
        arguments << "root@8.138.215.14:/var/www/html/picture/";

        connect(scp, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                [=](int exitCode, QProcess::ExitStatus exitStatus) {
            if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
                QMessageBox::information(this, "成功", "上传完成"); // 使用 this 作为父窗口
            } else {
                QString errorMessage = QString("上传失败 (代码: %1)\n%2")
                                      .arg(exitCode)
                                      .arg(QString::fromUtf8(scp->readAllStandardError()));
                QMessageBox::critical(this, "错误", errorMessage); // 使用 this 作为父窗口
            }
            scp->deleteLater();
        });

        connect(scp, static_cast<void (QProcess::*)(QProcess::ProcessError)>(&QProcess::errorOccurred),
                [=](QProcess::ProcessError error) {
            Q_UNUSED(error);
            QMessageBox::critical(this, "错误",
                                 QString("SCP 启动失败: %1").arg(scp->errorString())); // 使用 this 作为父窗口
            scp->deleteLater();
        });

        // 启动进程
        scp->start(pscpPath, arguments);

        // 设置超时（可选）
        QTimer::singleShot(30000, [=]() {
            if (scp->state() == QProcess::Running) {
                scp->kill(); // 超时强制终止
                QMessageBox::warning(this, "超时", "上传未在30秒内完成");
            }
        });
}


//// 上传选中记录的图片到服务器
//void DataInfoWindow::on_uploadserverButton_clicked()
//{
//        qDebug() << "on_uploadserverButton_clicked:\r\n";

//        // 1. 获取当前选中行
//        int currentRow = ui->tableWidget->currentRow();
//        if (currentRow == -1) {
//            QMessageBox::warning(this, "警告", "请先选择要上传的行！");
//            return;
//        }

//        // 2. 获取图片路径（假设图片路径存储在列2）
//        QString imagePath = ui->tableWidget->item(currentRow, 1)->text();
//        if (imagePath.isEmpty()) {
//            QMessageBox::warning(this, "警告", "该记录没有有效的图片路径！");
//            return;
//        }
////        else {
////            qDebug() << "该记录有有效的图片路径: " << imagePath;
////            QMessageBox::information(this, "成功", "该记录有有效的图片路径！");
////        }

//        // 3. 检查文件是否存在
//        QFile imageFile(imagePath);
//        if (!imageFile.exists()) {
//            QMessageBox::critical(this, "错误", "图片文件不存在：" + imagePath);
//            return;
//        }
////        else {
////            qDebug() << "图片文件存在: " << imagePath;
////            QMessageBox::information(this, "成功", "图片文件存在！");
////        }

//        // 检查文件是否存在
//        if (!QFile::exists(imagePath)) {
//            QMessageBox::critical(this, "错误", "本地图片不存在！");
//            return;
//        }

//        // 检查网络连通性
//        QProcess ping;
//        ping.start("ping", {"-n", "1", "8.138.215.14"});
//        if (!ping.waitForFinished(2000)) {
//            QMessageBox::warning(this, "警告", "服务器无法连通！");
//            return;
//        }
//        else {
//            QMessageBox::information(this, "成功", "服务器连接成功！");
//        }
//        // 检查windows系统下的"ping 8.138.215.14"命令是否连通
////        checkServer();

////        // 4. 使用SCP上传文件
////        QProcess scp; // 创建栈对象
////        QString remotePath = "root@8.138.215.14:/var/www/html/picture/";
////        QStringList args;
////        args << imagePath << remotePath;
////        qDebug() << "args: " << args;

////        scp.start("scp", args);
////        if (!scp.waitForFinished(60000)) { // 30秒超时
////            QMessageBox::critical(this, "错误", "上传超时（60s）：" + scp.errorString());
////            return;
////        }

////        if (scp.exitCode() != 0) {
////            QMessageBox::critical(this, "错误", "上传失败：\n" + scp.readAllStandardError());
////            return;
////        }

////        QMessageBox::information(this, "成功", "图片上传成功！");

//        // 4. 使用SCP上传文件
//        // 创建堆对象（避免随函数结束销毁）
//        QProcess *scp = new QProcess(this); // this 确保随窗口销毁时自动清理

//        // 连接信号槽处理完成事件
//        connect(scp, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
//            [=](int exitCode, QProcess::ExitStatus /*status*/) {  // 正确参数列表
//                if (exitCode == 0) {
//                    QMessageBox::information(this, "成功", "图片上传成功！");
//                } else {
//                    QMessageBox::critical(this, "错误",
//                        QString("上传失败：\n%1").arg(QString(scp->readAllStandardError())));
//                }
//                scp->deleteLater();
//            });
//        qDebug() << "imagePath: " << imagePath;
//        // 启动上传
//        QString remotePath = "root@8.138.215.14:/var/www/html/picture/";
//        scp->start("scp", {imagePath, remotePath});

//        // 设置超时（可选）
//        QTimer::singleShot(30000, [=]() {
//            if (scp->state() == QProcess::Running) {
//                scp->kill(); // 超时强制终止
//                QMessageBox::warning(this, "超时", "上传未在30秒内完成");
//            }
//        });
//}

////// 示例代码需根据库文档调整
////void uploadFile() {
////    QSsh::SshConnectionParameters params;
////    params.host = "8.138.215.14";
////    params.userName = "root";
////    params.authenticationType = QSsh::SshConnectionParameters::AuthenticationTypePublicKey;

////    QSsh::SshConnection connection(params);
////    connection.connectToHost();

////    // 上传文件（伪代码，具体参考库文档）
////    connection.uploadFile("1.mp3", "/var/www/html/picture/1.mp3");
////}

////void DataInfoWindow::uploadFile() {
////    QProcess scp;
////    scp.start("scp", {"1.mp3", "root@8.138.215.14:/var/www/html/picture"});
////    scp.waitForFinished();
////    qDebug() << "Output:" << scp.readAllStandardOutput();
////    qDebug() << "Error:" << scp.readAllStandardError();
////}
